home *** CD-ROM | disk | FTP | other *** search
- /* See the file Distribution for distribution terms.
- (c) Copyright 1994 Ari Halberstadt */
-
- /* A quick hack to test my threads library. A dialog is displayed with two
- counters, each incremented in its own thread. The display of the counters
- is updated once a second from a third thread. The "count1" line contains
- the value of the first counter, the "count2" line contains the value of
- the second counter. The "elapsed" line contains the number of ticks between
- updates (should be close to 60 ticks). The "remaining" line shows the number
- of ticks till the program automatically quits (about 30 seconds, or 1800
- ticks). Click the "Quit" button to quit the program, or "Raise Exception"
- to quit the program by raising an exception.
-
- While writing this I discovered that my threads library and THINK C's
- console library don't get along too great (I haven't tracked down exactly
- what's wrong), so I changed it to use a simple dialog.
-
- 94/02/10 aih - created */
-
- #include <limits.h>
- #include "ThreadLib.h"
-
- #define rDialog (128)
-
- /* dialog items */
- enum {
- iQuit = 5,
- iException,
- iCount1,
- iCount2,
- iElapsed,
- iRemaining,
- iLast
- };
-
- /* the counters */
- static long count1;
- static long count2;
-
- /* the threads */
- static ThreadHandle hthreadmain;
- static ThreadHandle hthread1;
- static ThreadHandle hthread2;
- static ThreadHandle hthread3;
-
- /* the dialog */
- static DialogPtr gDialog;
-
- /* initialize application heap */
- static void HeapInit(long stack, short masters)
- {
- SetApplLimit(GetApplLimit() - stack);
- MaxApplZone();
- while (masters-- > 0)
- MoreMasters();
- }
-
- /* initialize managers */
- static void ManagersInit(void)
- {
- EventRecord event;
- short i;
-
- /* standard initializations */
- InitGraf((Ptr) &thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(NULL);
- FlushEvents(everyEvent, 0);
- InitCursor();
-
- /* so first window will be frontmost */
- for (i = 0; i < 4; i++)
- EventAvail(everyEvent, &event);
- }
-
- /* thread to increment the first counter */
- static void thread1(void *data)
- {
- for (;;) {
- count1++;
- ThreadYield(0); /* runs this thread as often as possible */
- }
- }
-
- /* thread to increment the second counter */
- static void thread2(void *data)
- {
- for (;;) {
- count2++;
- ThreadYield(0); /* runs this thread as often as possible */
- }
- }
-
- /* thread to update display of counters in dialog */
- static void thread3(void *data)
- {
- TicksType ticks;
- short type;
- Handle item;
- Rect box;
- Str255 str;
-
- for (;;) {
- if (gDialog) {
- NumToString(count1, str);
- GetDItem(gDialog, iCount1, &type, &item, &box);
- SetIText(item, str);
- NumToString(count2, str);
- GetDItem(gDialog, iCount2, &type, &item, &box);
- SetIText(item, str);
- ticks = TickCount();
- ThreadYield(60); /* runs this thread every seconds */
- if (gDialog) {
- NumToString(TickCount() - ticks, str);
- GetDItem(gDialog, iElapsed, &type, &item, &box);
- SetIText(item, str);
- }
- }
- }
- }
-
- /* create all of the threads */
- static void ThreadsInit(void)
- {
- hthreadmain = ThreadBeginMain(NULL, NULL, NULL);
- hthread1 = ThreadBegin(thread1, NULL, NULL, NULL, 0);
- hthread2 = ThreadBegin(thread2, NULL, NULL, NULL, 0);
- hthread3 = ThreadBegin(thread3, NULL, NULL, NULL, 0);
- }
-
- /* dispose of all of the threads */
- static void ThreadsDispose(void)
- {
- ThreadEnd(hthread1);
- ThreadEnd(hthread2);
- ThreadEnd(hthread3);
- ThreadEnd(hthreadmain);
- }
-
- /* filter procedure for the dialog, quits when time has elapsed and allows
- other threads to run by calling ThreadYield */
- static pascal Boolean filter(DialogPtr dlg, EventRecord *event,
- short *itemHit)
- {
- static TicksType ticks;
- static TicksType stop;
- short type;
- Handle item;
- Rect box;
- Str255 str;
-
- if (! stop)
- stop = TickCount() + 60 * 30; /* run for 30 seconds */
- if (TickCount() >= stop) {
- *itemHit = iQuit;
- return(true);
- }
- if (TickCount() - ticks > 60) {
- NumToString(stop - TickCount(), str);
- GetDItem(dlg, iRemaining, &type, &item, &box);
- SetIText(item, str);
- ticks = TickCount();
- }
- if (event->what == nullEvent) {
- ThreadYield(60); /* runs this thread every second, when an event
- is pending, or when no other thread is
- scheduled */
- }
- return(false);
- }
-
- /* create the dialog and run the program */
- static void Run(void)
- {
- short item;
-
- TRY {
- gDialog = GetNewDialog(rDialog, NULL, (WindowPtr) -1);
- do {
- ModalDialog(filter, &item);
- switch (item) {
- case iException:
- FailOSErr(-1);
- break;
- }
- } while (item != iQuit);
- } CLEANUP {
- if (gDialog)
- DisposeDialog(gDialog);
- gDialog = NULL;
- } ENDTRY;
- }
-
- void main(void)
- {
- TRY {
- HeapInit(0, 4);
- ManagersInit();
- ThreadsInit();
- Run();
- } CLEANUP {
- ThreadsDispose();
- } ENDTRY;
- }
-